Classificatie is een ML taak waarbij een label voorspeld moet worden uit een mogelijke lijst van antwoorden.
Wanneer er slechts 2 mogelijke labels zijn dan noemt men dit binaire classificatie
Voorbeeld : je spam filter : een mail is spam of ham - je lost in dit geval een ja/nee vraag op
Wanneer er meerdere labels mogelijk zijn dan noemt men dit multiclass classificatie
Voorbeeld : herkennen van handgeschreven cijfers - het antwoord kan zijn : 0,1,...,9
Regressie is een ML taak waarbij een cijfer (continue waarde) voorspeld moet worden
Voorbeeld : iemand zijn leeftijd voorspellen, iemand zijn jaarlijks inkomen voorspellen, ...
De Engelse antropoloog Francis Galton ontdekte dat kinderen uitzonderlijke eigenschappen van hun ouders overerven, maar dat er wel een trend van regressie naar het midden bestaat. Lange ouders krijgen bijvoorbeeld lange kinderen en korte ouders korte kinderen, echter steeds minder nadrukkelijk. Galton noemde de analysemethode die hij gebruikte naar het door hem bestudeerde fenomeen: regressie. (from https://deafstudeerconsultant.nl/regressie-analyse-beginners/)
Regressie =
Als twee variabelen gecorreleerd zijn (ze veranderen samen), dan kan je de onafhankelijke variabele (degene die beïnvloed) gebruiken om de afhankelijke variabele (degene die wordt beïnvloed) te voorspellen. Dit voorspellingsmodel kan een rechte zijn (een lineair verband) men spreekt dan over lineaire regressie.
Voorbeelden :
Als er meerdere voorspellende variabelen zijn, dan spreken we over meervoudige lineaire regressie indien er slechts 2 zijn dan spreken we over enkelvoudige lineaire regressie.
Men zegt : lineaire regressie voorspelt de waarde van een afhankelijke variabele op basis van de waarde van een (of meer) onafhankelijke variabele(n) (ook wel verklarende of voorspellende variabelen genoemd).
In een ML setting :
de onafhankelijke variabelen zijn de features die de data beschrijven (zie Iris data set - 4 features: petal length, petal width, sepal length, sepal width)
de afhankelijke variabele = de target = de waarde die voorspeld moet worden
hoe weet je of de relatie tussen onafhankelijke en afhankelijke variabelen lineair is? -> zie Bias
Lineaire regressie heeft een simpel model representatie met weinig parameters nml. een rechte :
y=a0+a1∗xHierbij is y = de target, x = de enige feature en a0,a1 de parameters van het model. Om de rechte te zoeken die de relatie tussen x en y modelleert, volstaat het dus om op zoek te gaan naar a0 en a1. Betekenis van deze parameters :
helling en intercept :
Zoek de juist rechte :
Hierbij blijft y = de target, x1,…,xn = de n eatures en a0,…,an de parameters van het model. In dit geval moeten de parameters a1…an gezocht worden om de vergelijking van een hoger dimensioneel vlak (= hypervlak) te vinden.
3D hypervlak
Een kost functie berekent de error tussen geschatte en werkelijke waarden. Deze moet dus geminimaliseerd worden. Meestal wordt er gekozen voor de Mean Squared Error functie (methode van de kleinste kwadraten) :
MSE=1nn∑i=1(yi−predi)2Taak : Zoek de waarden a0…an zodat de MSE functie minimaal is. De leertaak is m.a.w. omgezet naar een taak van zoeken dankzij de keuze van de representatie !
MIN(MSE)=MIN(1ngroottedatset∑i=1(yi−n=nrfeatures∑j=0aj∗xij)2)Gradient descent is een manier om de parameters van de rechte / hypervlak te zoeken zodat de kostfunctie geminimaliseerd wordt. Begin met random waarden, bereken de kostfunctie. Iteratief wordt in elke stap de waarden voor de parameters gewijzigd zodat de fout telkens kleiner wordt.
Deze wijziging gebeurt aan de hand van de gradiënt van die parameter : de afgeleide van de MRE naar die parameter.
Goed nieuws : sklearn module bevat een LineairRegression model dat automatisch de coëfficienten van de rechte (of het hypervlak) zoekt via minimalisatie van de MSE functie !
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
X, y = make_wave(n_samples=60)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
lr = LinearRegression().fit(X_train, y_train)
print("lr.coef_:", lr.coef_)
print("lr.intercept_:", lr.intercept_)
lr.coef_: [0.39390555] lr.intercept_: -0.031804343026759746
print("Training set score: {:.2f}".format(lr.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lr.score(X_test, y_test)))
Training set score: 0.67 Test set score: 0.66
zowel training als test set accuracy scoort laag en gelijkaardig (geen overfitting dus - eerder underfitting)
Gekende real-world dataset uit de jaren '70 waarbij huisprijzen moeten voorspeld worden in bepaalde buurten van Boston met features zoals crime rate, highway accessibility en proximity to the Charles river. In totaal zijn er 13 features en 506 datapoints. https://towardsdatascience.com/linear-regression-on-boston-housing-dataset
Data Set Characteristics:
:Number of Instances: 506
:Number of Attributes: 13 numeric/categorical predictive. Median Value (attribute 14) is usually the target.
:Attribute Information (in order):
- CRIM per capita crime rate by town
- ZN proportion of residential land zoned for lots over 25,000 sq.ft.
- INDUS proportion of non-retail business acres per town
- CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)
- NOX nitric oxides concentration (parts per 10 million)
- RM average number of rooms per dwelling
- AGE proportion of owner-occupied units built prior to 1940
- DIS weighted distances to five Boston employment centres
- RAD index of accessibility to radial highways
- TAX full-value property-tax rate per $10,000
- PTRATIO pupil-teacher ratio by town
- B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town
- LSTAT % lower status of the population
- MEDV Median value of owner-occupied homes in $1000's
:Missing Attribute Values: None
X, y = load_extended_boston()
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
lr = LinearRegression().fit(X_train, y_train)
print("Training set score: {:.2f}".format(lr.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lr.score(X_test, y_test)))
Training set score: 0.95 Test set score: 0.61
De discrepancy tussen test en training accuracy duidt nu wel duidelijk op overfitting ! -> zie verder regularizatie
Correlatie drukt de samenhang tussen 2 variabelen uit. Deze kan :
De mate van correlatie tussen twee variabelen wordt uitgedrukt in de correlatiecoëfficiënt. De waarde daarvan kan variëren tussen –1 en +1. Daarbij betekent 0: geen lineaire samenhang, +1: een perfecte positieve lineaire samenhang – 1: een perfecte negatieve lineaire samenhang.
Hoe verder de correlatiecoëfficiënt verwijderd is van 0, hoe sterker de correlatie. zie bvb de Pearson correlatiecoëfficiënt die je kan berekenen via steekproeven.
Let wel : Een correlatiecoëfficiënt van 0 wil zeggen dat er totaal geen lineaire samenhang is. Er kan echter wel een kwadratisch of ander verband zijn.
Een correlatie kan je niet gebruiken om causaliteit (oorzaak-verband) te bewijzen. Je kan dit ook niet met regressie, maar een aanwezige correlatie kan je wel gebruiken om regressie (voorspellingen te gaan doen)
Er blijkt de voorbije jaren een correlatie te zijn tussen de afstand tussen de Aarde en de komeet van Halley en de benzineprijs. Deze correlatie is zeer sterk, en het is duidelijk dat er geen oorzakelijk verband is.
http://www.psyblog.nl/2014/02/06/correlatie-causaliteitijsjes-piraten-en-de-media/
In dit model werd er rekening gehouden met alle aanwezige features. Hoe kunnnen de meest relevante features gevonden worden? Bereken voor elke 2 features hun correlatie. De correlatiematrix kan aantonen welke features hoog gecorreleerd zijn met de target feature (MEDV). Bijvoorbeeld feature RM heeft een sterke positieve correlatie 0.7, terwijl LSTAT een hoge negatieve correlatie heeft met MDEV : -0.74. Wanneer 2 features onderling hoog gecorreleerd zijn, hoef je maar 1 van de 2 in het voorspellend model te gebruiken : bvb RAD en TAX zijn onderling gecorreleerd met 0.91
Regularizatie legt extra voorwaarden op aan het minimalisatieproces om overfitting te vermijden. Dus de coëfficienten moeten zo gekozen worden dat de kostfunctie nog steeds minimaal blijft; maar hierbovenop wil men ook de complexiteit van het model zelf verminderen (en dus het model algemener maken).
Dit kan bv. door de coëfficienten a_j zo klein mogelijk te kiezen : elke coëfficient a_i moet zo dicht mogelijk tegen 0 gekozen worden zonder de kwaliteit van het resultaat te verminderen. Een feature moet m.a.w. een zo klein mogelijke invloed op het resultaat uitoefenen zonder aan kwaliteit in te boeten. (de helling moet dus zo klein mogelijk gehouden worden).
Dit geeft een extra parameter \bf{\alpha} waarmee het model kan aangepast worden (lees verbeterd worden cfr het aantal buren bij K-NN). Hoe kleiner \alpha gekozen wordt, hoe dichter het model aanleunt bij het klassieke lineaire regressiemodel
from sklearn.linear_model import Ridge
ridge = Ridge().fit(X_train, y_train)
print("Training set score: {:.2f}".format(ridge.score(X_train, y_train)))
print("Test set score: {:.2f}".format(ridge.score(X_test, y_test)))
Training set score: 0.89 Test set score: 0.75
ridge10 = Ridge(alpha=10).fit(X_train, y_train)
print("Training set score: {:.2f}".format(ridge10.score(X_train, y_train)))
print("Test set score: {:.2f}".format(ridge10.score(X_test, y_test)))
Training set score: 0.79 Test set score: 0.64
ridge01 = Ridge(alpha=0.1).fit(X_train, y_train)
print("Training set score: {:.2f}".format(ridge01.score(X_train, y_train)))
print("Test set score: {:.2f}".format(ridge01.score(X_test, y_test)))
Training set score: 0.93 Test set score: 0.77
Waarden van de coëfficienten voor verschillende \alpha
de score op de trainingset is bij beide hoger dan deze van de test set
de score op de trainingset is hoger bij lineaire regressie (wegens overfitting) maar de score op de test set is beter bij Ridge !
Lineaire regressie heeft veel datapunten nodig om effectief iets te leren (pas vanaf 400 datapunten). Ridge scoort dus veel beter op kleinere datsets.
De regularizatie wordt minder belangrijk naarmate de grootte van de dataset toeneemt ! De rede hiervoor is dat overfitting minder kans heeft bij grotere datsets.
Dezelfde extra parameter \alpha kan gebruikt worden om het model beter te leren instellen.
Het grote verschil met Ridge regressie is dat de coëfficienten nu daadwerkelijk 0 kunnen worden en er dus features geëlimineerd worden! Lasso regressie kan dus gezien worden als een feature selectie techniek
from sklearn.linear_model import Lasso
lasso = Lasso().fit(X_train, y_train)
print("Training set score: {:.2f}".format(lasso.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lasso.score(X_test, y_test)))
print("Number of features used:", np.sum(lasso.coef_ != 0))
Training set score: 0.29 Test set score: 0.21 Number of features used: 4
# we increase the default setting of "max_iter",
# otherwise the model would warn us that we should increase max_iter.
lasso001 = Lasso(alpha=0.01, max_iter=100000).fit(X_train, y_train)
print("Training set score: {:.2f}".format(lasso001.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lasso001.score(X_test, y_test)))
print("Number of features used:", np.sum(lasso001.coef_ != 0))
Training set score: 0.90 Test set score: 0.77 Number of features used: 33
lasso00001 = Lasso(alpha=0.0001, max_iter=100000).fit(X_train, y_train)
print("Training set score: {:.2f}".format(lasso00001.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lasso00001.score(X_test, y_test)))
print("Number of features used:", np.sum(lasso00001.coef_ != 0))
Training set score: 0.95 Test set score: 0.64 Number of features used: 96
Ridge (\alpha = 0.1) presteert gelijkwaardig als Lasso (\alpha = 0.01) alleen heeft Lasso veel minder features gebruikt!
Lasso geeft je een minder complex model doordat minder features gebruikt worden (vele coëfficienten worden 0). Wanneer er niet zoveel features zijn wordt Ridge geprefereerd.
Soms worden beide regularizaties samen gebruikt.
De taak is nu om een rechte of hypervlak te vinden die zal optreden als grens om beslissingen te nemen omtrent classificatie. Deze rechte of hypervlak noemt men ook wel decision boundaries. Data die perfect voospeld kan worden door lineaire modellen noemt men lineair separeerbaar.
De vergelijking van een rechte / hyperplane wordt nu op de volgende manier gebruikt :
\begin{equation} y_{predict} = a_0 + a_1 * x_1 + a_2 * x_2 , \ldots , + a_n * x_n > 0 \end{equation}Wanneer de voorspelde waarde y postief is zal de klasse +1 / ja voorspeld worden, indien ze negatief is zal de klasse -1 / neen voorspeld worden.
Opnieuw moeten de coëfficienten a_j gezocht worden om hier het aantal misclassificaties te minimaliseren (i.p.v. een kostfunctie minimaliseren, spreekt men hier van een loss-functie)
Ondanks zijn naam is het wel degelijk een classifcatiealgoritme.
\begin{equation} y_{predict} = ln(\frac{p_y}{1-p_y}) = a_0 + a_1 * x_1 + a_2 * x_2 , \ldots , + a_n * x_n \end{equation}waarbij p_y = de kans op waarde 1 voor y en dus 1-p = de kans op waarde 0 voor y.
In plaats van de parameters te zoeken die een kostfunctie minimaliseren, worden hier parameters gezocht die de likelihood op het voorkomen van de trainingsdata maximaliseren. Maximum Likelhood optimization zoekt deze parameters die de fouten in de kansen op de trainingsdata minimaliseren en dus de trainingsdata zou goed mogelijk verklaren.
Regularizatie kan eveneens toegepast worden om overfitting te vermijden. Hier wordt dit geregeld via parameter C
Stel we moeten voorspellen op basis van de lengte van een persoon of deze mannelijk of vrouwelijk is. Dit is een binaire classificatie op basis van 1 feature. We zoeken dus een waarde voor parameter a_0 en a_1. Stel ons leermodel geeft volgende gegevens a_0 = -100 en a_1 = 0.6. Welke klasse wordt dan voorspeld voor een persoon die 1m50 groot is ?
\begin{equation} ln(\frac{p_y}{1-p_y}) = a_0 + a_1 * x_1 = -100 + 0.6 (150) = -10 \\ \frac{p_y}{1 - p_y} = EXP^{(-10)} \\ p_y = \frac{EXP^{(-10)}}{1 +EXP^{(-10)} } \\ p_y = 0.0000453978687 \end{equation}De kans om mannelijk te zijn bij een lengte van 150cm is dus heel klein! De classificatie gaat als volgt :
\begin{equation} p(male) < 0.5 -> 0 \\ p(male) \ge 0.5 -> 1 \end{equation}Meestal wordt de one versus rest methode gebruikt. Deze doet een binaire classificatie voor elke klasse waarbij deze klasses wordt gescheiden van de rest via een lineair model. Er worden meerdere binaire classifiers geleerd. Bij voorspelling van een nieuw datapunt worden al deze binaire classifiers gebruikt om een voorspelling te doen. Deze die de hoogste kans geeft wordt gebruikt om de voorspelling te maken.
from sklearn.datasets import load_digits
digits = load_digits()
# Print to show there are 1797 images (8 by 8 images for a dimensionality of 64)
print('Image Data Shape' , digits.data.shape)
# Print to show there are 1797 labels (integers from 0–9)
print("Label Data Shape", digits.target.shape)
Image Data Shape (1797, 64) Label Data Shape (1797,)
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(20,4))
for index, (image, label) in enumerate(zip(digits.data[0:5], digits.target[0:5])):
plt.subplot(1, 5, index + 1)
plt.imshow(np.reshape(image, (8,8)), cmap=plt.cm.gray)
plt.title('Training: %i\n' % label, fontsize = 20)
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(digits.data, digits.target, test_size=0.25, random_state=0)
logisticRegr = LogisticRegression(solver='liblinear', multi_class = 'auto')
logisticRegr
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, max_iter=100, multi_class='auto',
n_jobs=None, penalty='l2', random_state=None, solver='liblinear',
tol=0.0001, verbose=0, warm_start=False)
logisticRegr.fit(x_train, y_train)
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, max_iter=100, multi_class='auto',
n_jobs=None, penalty='l2', random_state=None, solver='liblinear',
tol=0.0001, verbose=0, warm_start=False)
print(logisticRegr.predict(x_test[0].reshape(1,-1)))
print(logisticRegr.predict(x_test[0:10]))
[2] [2 8 2 6 6 7 1 9 8 5]
score = logisticRegr.score(x_test, y_test)
print(score)
0.9533333333333334
Elk ML algoritme dat in staat is om te generalizeren over de trainingsdata heen draagt een zekere bias met zich mee. Dit is een algoritme bias, of inductieve bias.
K-NN : de classificatie van een datapunt wordt verondersteld om gelijkaardig te zijn aan dat van zijn buren, dit zijn andere datapunten uit de trainingsset die dichtbij zijn volgens typisch de Euclidische afstandsmaat
Lineaire modellen : men veronderstelt een lineair verband tussen de features en de target, of men veronderstelt dat de datapunten lineair separeerbaar zijn (classificatie). Dit heeft als gevolg dat data soms voorbereid moet worden :
https://thenextweb.com/contributors/2018/10/27/4-human-caused-biases-machine-learning/
Introduction to Machine Learning Algorithms: Linear Regression https://towardsdatascience.com/introduction-to-machine-learning-algorithms-linear-regression-14c4e325882a
Linear Regression for Machine Learning https://machinelearningmastery.com/linear-regression-for-machine-learning/
Linear Regression on Boston Housing Dataset https://towardsdatascience.com/linear-regression-on-boston-housing-dataset-f409b7e4a155
Ridge and Lasso Regression: A Complete Guide with Python Scikit-Learn https://towardsdatascience.com/ridge-and-lasso-regression-a-complete-guide-with-python-scikit-learn-e20e34bcbf0b
Logistic Regression using Python (scikit-learn) <https://towardsdatascience.com/logistic-regression-using-python- sklearn-numpy-mnist-handwriting-recognition-matplotlib-a6b31e2b166a>